package com.weixing.mall.provider.controller.common;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.weixing.mall.base.constant.DatePattern;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.base.utils.EnumUtil;
import com.weixing.mall.base.wrapper.Result;
import com.weixing.mall.base.wrapper.ResultUtil;
import com.weixing.mall.core.annotation.NoNeedAccess;
import com.weixing.mall.base.enums.IsEnableEnum;
import com.weixing.mall.base.enums.WhetherEnum;
import com.weixing.mall.core.support.BaseController;
import com.weixing.mall.core.support.auth.AgentAuth;
import com.weixing.mall.core.support.auth.AuthUtil;
import com.weixing.mall.core.support.auth.SysAuth;
import com.weixing.mall.provider.api.model.enums.AgentLevelEnum;
import com.weixing.mall.provider.api.model.enums.TreeRoleEnum;
import com.weixing.mall.provider.api.model.vo.AgentTreeVo;
import com.weixing.mall.provider.api.model.vo.AgentVo;
import com.weixing.mall.provider.api.model.vo.KefuVo;
import com.weixing.mall.provider.api.service.SysUserRpcService;
import com.weixing.mall.provider.model.domain.Agent;
import com.weixing.mall.provider.model.domain.AgentBonusGroup;
import com.weixing.mall.provider.service.IAgentService;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 代理商通用结构树
 *
 * @author siashan
 * @since v1.0
 **/
@RestController
@RequestMapping("/agent/tree")
@Validated
public class AgentTreeController extends BaseController {



    private static final String TRADE_FLAG_TRUE = "1";
    private static final String TRADE_FLAG_FALSE = "0";

    @Autowired
    private SysUserRpcService sysUserRpcService;
    @Autowired
    private IAgentService agentService;


    /**
     * 代理商通用结构树--客服主管专用
     *
     * @return 代理结构树
     */
    @GetMapping("/kefu/all")
    public Result<List<AgentTreeVo>> tree() {
        List<KefuVo> voList = loadKefuList();
        // 最终返回的代理结构树
        List<Agent> agents = agentService.listAll();
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        if (CollUtil.isNotEmpty(voList)) {
            voList.forEach(kefuVo -> {
                int cnt = agentService.countKefuGroupCnt(kefuVo.getId());
                AgentTreeVo treeVo = createTreeVoFromKefuVo(kefuVo, cnt);
                wrapTreeVos(agents, treeVos, kefuVo, treeVo);
            });

        }
        return ResultUtil.success(treeVos);
    }




    /**
     * 代理商通用结构树--后台客服专用
     *
     * @return 代理商结构树
     */
    @GetMapping("/kefu")
    public Result<List<AgentTreeVo>> treeForKefu() {
        Long uid = AuthUtil.getSysExt().getUid();
        KefuVo kefuVo = loadKefuVo(uid);
        // 最终返回的代理结构树
        List<Agent> agents = agentService.listAllByKefuId(uid);
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        int cnt = agentService.countKefuGroupCnt(kefuVo.getId());
        AgentTreeVo treeVo = createTreeVoFromKefuVo(kefuVo, cnt);
        // 顶级节点
        wrapTreeVos(agents, treeVos, kefuVo, treeVo);
        return ResultUtil.success(treeVos);
    }

    /**
     * 包装代理结构树
     * @param agents    代理列表
     * @param treeVos   结构树列表
     * @param kefuVo    客服节点
     * @param treeVo    树节点
     */
    private void wrapTreeVos( List<Agent> agents, List<AgentTreeVo> treeVos, KefuVo kefuVo, AgentTreeVo treeVo) {
        Date now = new Date();
        // 顶级节点
        List<AgentTreeVo> rootList = Lists.newArrayList();
        List<Agent> agents1 = agents.stream().filter((Agent a) -> a.getParentId().longValue() == 0 && a.getCustomerId().longValue() == kefuVo.getId().longValue()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(agents1)) {
            for (Agent agent : agents1) {
                AgentTreeVo treeVo1 = createTreeVo(now, agent, null);
                //  递归包装child
                wrapper(treeVo1, agents, now);
                rootList.add(treeVo1);
            }
        }
        treeVo.setC(rootList);
        treeVos.add(treeVo);
        agents.removeAll(agents1);
    }

    /**
     * 代理商通用结构树--代理后台专用
     *
     * @return 代理商结构树
     */
    @GetMapping("agent")
    public Result<List<AgentTreeVo>> treeForAgent() {
        Long agentId = AuthUtil.getAgentExt().getAid();
        return ResultUtil.success(getAgentTreeVos(agentId, "0"));
    }


    /**
     * 代理商通用结构树--查询指定代理的结构树
     *
     * @param agentId   选中的代理商id
     * @return 代理商结构树
     */
    @GetMapping("agent/checked/{agentId}")
    public Result<List<AgentTreeVo>> treeForCheckedAgent(@PathVariable Long agentId) {
        return ResultUtil.success(getAgentTreeVos(agentId, "0"));
    }


    /**
     * 代理商通用结构树--APP端代理专用
     *
     * @param tradeFlag  是否只展示有交易的代理  0 否  1 是
     * @return 代理商结构树
     */
    @GetMapping("agent/app")
    public Result<List<AgentTreeVo>> treeForAppAgent(@RequestParam(value = "tradeFlag", defaultValue = "0") String tradeFlag) {
        return ResultUtil.success(getAgentTreeVos(AuthUtil.getMemberExt().getAbid(), tradeFlag));
    }


    @ApiOperation(value = "代理商结构树--领导看板")
    @GetMapping("tree/leader")
    @NoNeedAccess
    public Result treeForLeaderShow(String agentName) {
        //查询所有代理商
        QueryWrapper<Agent> qw = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(agentName)) {
            qw.like("agent_name", agentName);
        }
        qw.eq("is_enable", IsEnableEnum.ENABLE.getValue())
                .eq("is_bind", WhetherEnum.YES.getValue())
                .orderByAsc("id");
        //封装代理商结构树
        List<Agent> allAgentList = agentService.list(qw);
        //树装载
        List<Map<String, Object>> parentList = Lists.newArrayList();
        for (Agent a : allAgentList) {
            if (StrUtil.isNotEmpty(agentName)) {//以名称搜索结果为顶级
                //初始数量
                Integer teamNum = 0;
                Map<String, Object> parentMap = new HashMap<>();
                loadInfo(a, parentMap);
                loadChild(a.getId(), parentMap, allAgentList, teamNum);
                parentList.add(parentMap);
            } else {//默认以经销商一级为顶级
                if (AgentLevelEnum.DEALER.getValue().equals(a.getAgentLevel())) {
                    //初始数量
                    Integer teamNum = 0;
                    Map<String, Object> parentMap = new HashMap<>();
                    loadInfo(a, parentMap);
                    loadChild(a.getId(), parentMap, allAgentList, teamNum);
                    parentList.add(parentMap);
                }
            }
        }
        return ResultUtil.success(parentList);
    }

    private void loadChild(Long parentId, Map<String, Object> parentMap, List<Agent> allAgentList, Integer teamNum) {
        List<Map<String, Object>> childList = Lists.newArrayList();
        for (Agent a : allAgentList) {
            if (parentId.equals(a.getParentId())) {
                Map<String, Object> childMap = new HashMap<>();
                loadInfo(a, childMap);
                loadChild(a.getId(), childMap, allAgentList, teamNum);
                childList.add(childMap);
            }
        }
        parentMap.put("child", childList);
        parentMap.put("teamNum", teamNum + childList.size());
    }

    private void loadInfo(Agent a, Map<String, Object> Map) {
        Map.put("id", a.getId());
        Map.put("name", a.getAgentName());
        Map.put("mobile", a.getMobile());
        Map.put("wechat", a.getWechatNum());

        Map.put("parentId", a.getParentId());
        Map.put("level", a.getAgentLevel());
    }


    /**
     * 代理商通用结构树--推荐人列表（客服专员，管理员）
     *
     * @return 代理结构树
     */
    @ApiOperation(value = "代理商通用结构树--推荐人列表（客服专员，管理员）")
    @GetMapping("/bonus")
    public Result<List<AgentTreeVo>> treeForBonus() {
        Date now = new Date();
        List<KefuVo> voList = loadKefuList();
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        List<Agent> rootList = agentService.selectObligee(null);
        if (CollUtil.isNotEmpty(voList)) {
            voList.forEach(kefuVo -> {
                AgentTreeVo treeVo = createTreeVoFromKefuVo(kefuVo, null);
                // 经销商
                List<Agent> agents1 = rootList.stream().filter((Agent a) -> a.getCustomerId().longValue() == kefuVo.getId().longValue()).collect(Collectors.toList());

                List<AgentTreeVo> children = Lists.newArrayList();
                if (CollUtil.isNotEmpty(agents1)) {
                    List<Agent> childList = agentService.selectObligeeChild(null);
                    AgentTreeVo child = null;
                    for (Agent agent : agents1) {
                        child = createTreeVo(now, agent, null);
                        // 查询是否有下级
                        wrapperBonus(child, childList);
                        children.add(child);
                    }
                }
                treeVo.setC(children);
                treeVos.add(treeVo);
            });

        }
        return ResultUtil.success(treeVos);
    }


    /**
     * 代理商通用结构树--推荐人列表(客服专用)
     *
     * @return 代理结构树
     */
    @ApiOperation(value = "代理商通用结构树--推荐人列表(客服专用)")
    @GetMapping("bonus/kefu")
    public Result<List<AgentTreeVo>> treeForBonusForKefu() {
        Date now = new Date();
        SysAuth sysAuth = AuthUtil.getSysExt();
        KefuVo kefuVo = loadKefuVo(sysAuth.getUid());
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        AgentTreeVo treeVo = createTreeVoFromKefuVo(kefuVo, null);
        // 经销商
        List<Agent> rootList = agentService.selectObligee(kefuVo.getId());
        List<AgentTreeVo> children = Lists.newArrayList();
        if (CollUtil.isNotEmpty(rootList)) {
            List<Agent> childList = agentService.selectObligeeChild(null);
            AgentTreeVo child = null;
            for (Agent agent : rootList) {
                child = createTreeVo(now, agent, null);
                wrapperBonus(child, childList);
                children.add(child);
            }
        }
        treeVo.setC(children);
        treeVos.add(treeVo);


        return ResultUtil.success(treeVos);
    }

    /**
     * 代理商通用结构树--推荐人列表(代理专用)
     * @return 代理结构树
     */
    @GetMapping("bonus/agent")
    public Result<List<AgentTreeVo>> treeForBonusForAgent() {
        Date now = new Date();
        AgentAuth agentAuth = AuthUtil.getAgentExt();
        List<AgentBonusGroup> bonusGroups = agentService.selectObligeeOwn(agentAuth.getAid());
        Agent rootAgent = null;
        if (CollUtil.isNotEmpty(bonusGroups)) {
            rootAgent = agentService.getById(agentAuth.getAid());
        }
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        if (null != rootAgent) {
            AgentTreeVo treeVo = createTreeVo(now, rootAgent, null);
            List<Agent> childList = agentService.selectObligeeChild(null);
            wrapperBonus(treeVo, childList);
            treeVos.add(treeVo);
        }
        return ResultUtil.success(treeVos);
    }

    /**
     * 代理商通用结构树--推荐人列表<分红发放人>（客服专员，管理员）
     *
     * @return 代理结构树
     */
    @GetMapping("/ob/all")
    public Result<List<AgentTreeVo>> treeForOb() {
        Date now = new Date();
        List<KefuVo> voList = loadKefuList();
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        List<Agent> rootList = agentService.selectObligor(null);
        if (CollUtil.isNotEmpty(voList)) {
            voList.forEach(kefuVo -> {
                AgentTreeVo treeVo = createTreeVoFromKefuVo(kefuVo, null);
                // 经销商
                List<Agent> agents1 = rootList.stream().filter((Agent a) -> a.getCustomerId().longValue() == kefuVo.getId().longValue()).collect(Collectors.toList());
                List<AgentTreeVo> children = Lists.newArrayList();
                if (CollUtil.isNotEmpty(agents1)) {
                    AgentTreeVo child = null;
                    for (Agent agent : agents1) {
                        child = createTreeVo(now, agent, null);
                        children.add(child);
                    }
                }
                treeVo.setC(children);
                treeVos.add(treeVo);
            });

        }
        return ResultUtil.success(treeVos);
    }

    /**
     * 代理商通用结构树--推荐人列表<分红发放人>(客服专用)
     * @return 代理结构树
     */
    @GetMapping("ob/kefu")
    public Result<List<AgentTreeVo>> treeForBonusForObKefu() {
        Date now = new Date();
        SysAuth sysAuth = AuthUtil.getSysExt();
        KefuVo kefuVo = loadKefuVo(sysAuth.getUid());
        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        AgentTreeVo treeVo = createTreeVoFromKefuVo(kefuVo, null);
        // 经销商
        List<Agent> rootList = agentService.selectObligor(kefuVo.getId());
        List<AgentTreeVo> children = Lists.newArrayList();
        if (CollUtil.isNotEmpty(rootList)) {
            AgentTreeVo child = null;
            for (Agent agent : rootList) {
                child = createTreeVo(now, agent, null);
                children.add(child);
            }
        }
        treeVo.setC(children);
        treeVos.add(treeVo);
        return ResultUtil.success(treeVos);
    }


    private void wrapperBonus(AgentTreeVo voNode, List<Agent> agents) {
        List<Agent> childList = agents.stream().filter((Agent a) -> a.getParentId().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(childList)) {
            AgentTreeVo child = null;
            List<AgentTreeVo> children = Lists.newArrayList();
            for (Agent agent : childList) {
                child = createTreeVo(null,agent,null);
                children.add(child);
            }
            voNode.setC(children);
        }
    }


    /**
     * 递归包装代理结构树
     *
     * @param voNode   代理节点
     * @param agents   代理商列表
     * @param now       当前时间
     */
    private void wrapper(AgentTreeVo voNode, List<Agent> agents, Date now) {
        List<AgentTreeVo> rootList = Lists.newArrayList();
        List<Agent> agents1 = agents.stream().filter((Agent a) -> a.getParentId().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(agents1)) {
            for (Agent agent : agents1) {
                AgentTreeVo treeVo1 = createTreeVo(now, agent, null);
                //  递归包装child
                wrapper(treeVo1, agents, now);
                rootList.add(treeVo1);
            }
            agents.removeAll(agents1);
        }
        voNode.setC(rootList);

    }


    private void wrapperWithTradeFlag(AgentTreeVo voNode, List<Agent> agents) {
        String today = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
        if (CollUtil.isNotEmpty(agents)) {
            wrapperFilter(today, voNode, agents);
        }
    }

    private void wrapperFilter(String today, AgentTreeVo voNode, List<Agent> agents) {
        //        CNM! 什么尼玛的破需求,看不动了
        //        我要崩溃了！！！
        //        效果出来了，我好方
        List<AgentTreeVo> children = Lists.newArrayList();
        AgentTreeVo child = null;
        int cLevel = voNode.getL().intValue() + 1;
        while (cLevel < 5) {
            int finalCLevel = cLevel;
            List<Agent> childs = Lists.newArrayList();

            switch (voNode.getL()) {
                case 1:
                    childs = agents.stream().filter((Agent m1) -> m1.getAgentLevel().intValue() == finalCLevel && m1.getDealerId().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
                    break;
                case 2:
                    childs = agents.stream().filter((Agent m1) -> m1.getAgentLevel().intValue() == finalCLevel && m1.getLevel1st().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
                    break;
                case 3:
                    childs = agents.stream().filter((Agent m1) -> m1.getAgentLevel().intValue() == finalCLevel && m1.getLevel2nd().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
                    break;
                case 4:
                    childs = agents.stream().filter((Agent m1) -> m1.getAgentLevel().intValue() == finalCLevel && m1.getLevel3rd().longValue() == voNode.getId().longValue()).collect(Collectors.toList());
                    break;
                default:
                    break;
            }


            if (CollUtil.isNotEmpty(childs)) {
                List<Agent> dropList = Lists.newArrayList();
                for (Agent agent : childs) {
                    String tradeDate = StringUtil.isBlank(agent.getTradeDate()) ? "" : agent.getTradeDate();
                    if (today.equals(tradeDate)) {
                        child = createTreeVo(null,agent,null);
                        children.add(child);
                        wrapperFilter(today, child, agents);
                    }
                    dropList.add(agent);
                }
                agents.removeAll(dropList);
            }
            cLevel += 1;
        }
        voNode.setC(children);
    }

    /**
     * 获取代理结构树
     *
     * @param agentId           代理id
     * @param tradeFlag         是否只展示有交易的代理  0 否  1 是
     * @return 代理结构树
     */
    private List<AgentTreeVo> getAgentTreeVos(long agentId, String tradeFlag) {
        Date now = new Date();
        Agent rootAgent = agentService.getById(agentId);
        int cnt = agentService.countAgentGroupCnt(rootAgent.getId(), rootAgent.getAgentLevel());
        List<Agent> agents = agentService.listAllByAgentIdAndAgentLevel(agentId, rootAgent.getAgentLevel());

        // 最终返回的代理结构树
        List<AgentTreeVo> treeVos = Lists.newArrayList();
        AgentTreeVo treeVo = createTreeVo(now, rootAgent, cnt);
        if (TRADE_FLAG_TRUE.equals(tradeFlag)) {
            wrapperWithTradeFlag(treeVo, agents);
        } else {
            wrapper(treeVo, agents, now);
        }
        treeVos.add(treeVo);
        return treeVos;
    }

    /**
     * 创建AgentTreeVo对象
     * @param now  当前时间
     * @param agent  代理对象
     * @param cnt   下级数量
     * @return AgentTreeVo对象
     */
    private AgentTreeVo createTreeVo(Date now, Agent agent, Integer cnt) {
        AgentTreeVo treeVo = new AgentTreeVo();
        treeVo.setId(agent.getId());
        treeVo.setCt(cnt);
        treeVo.setR(TreeRoleEnum.AGENT.getValue());
        treeVo.setRn(EnumUtil.getIEnum(AgentLevelEnum.class, agent.getAgentLevel()).getShortName());
        treeVo.setN(agent.getAgentName());
        treeVo.setL(agent.getAgentLevel());
        treeVo.setIe(agent.getIsEnable());
        treeVo.setAn(agent.getAgentSn());
        treeVo.setM(agent.getMobile());
        if (null != now) {
            treeVo.setIm(DateUtil.compare(now, agent.getMaturityTime()) > 0 ? 1 : 0);
        }
        return treeVo;
    }

    /**
     * 创建AgentTreeVo对象
     * @param kefuVo  客服对象信息
     * @param cnt   下级数量
     * @return AgentTreeVo对象
     */
    private AgentTreeVo createTreeVoFromKefuVo(KefuVo kefuVo, Integer cnt) {
        AgentTreeVo treeVo = new AgentTreeVo();
        treeVo.setId(kefuVo.getId());
        treeVo.setR(TreeRoleEnum.KEFU.getValue());
        treeVo.setRn(TreeRoleEnum.KEFU.getDesp());
        treeVo.setN(kefuVo.getRealName());
        treeVo.setCt(cnt);
        treeVo.setAn("");
        treeVo.setL(0);
        treeVo.setM(kefuVo.getMobile());
        return treeVo;
    }

    /**
     * 加载客服列表
     *
     * @return 客服列表
     */
    private List<KefuVo> loadKefuList() {
        Result<List<KefuVo>> kefuVoResult = sysUserRpcService.loadKefu();
        if (!kefuVoResult.isSuccess()) {
            throw new BusinessException("加载代理结构树失败【查询客服节点异常】，请联系管理员解决");
        }
        return kefuVoResult.getData();
    }

    /**
     * 加载客服
     *
     * @return 客服
     */
    private KefuVo loadKefuVo(Long kefuId) {
        Result<KefuVo> kefuVoResult = sysUserRpcService.loadKefuById(kefuId);
        if (!kefuVoResult.isSuccess()) {
            throw new BusinessException("加载代理结构树失败【查询客服节点异常】，请联系管理员解决");
        }
        return kefuVoResult.getData();
    }

    @ApiOperation(value = "查询有分红关系的代理")
    @GetMapping("bonusAgent/{agentId}")
    public Result bonusAgent(@PathVariable Long agentId) {
        List<AgentVo> agents = agentService.selectBonusAgent(agentId);
        return ResultUtil.success(agents);
    }
}
